var elLaunch = {
    observerService: null,
    stringBundle: null,
    os: null,
    init: function()
    {
        elLaunch.observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
        elLaunch.observerService.addObserver(elLaunch, "ellaunch-launch-request", false);

        elLaunch.stringBundle = Components.classes['@mozilla.org/intl/stringbundle;1'].getService(Components.interfaces.nsIStringBundleService).createBundle("chrome://ellaunch/locale/ellaunch_overlay.properties");
        elLaunch.os = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
        var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader)
        if (elLaunch.os == "WINNT") {
            loader.loadSubScript("chrome://ellaunch/content/data_win32.js");
        } else {
            loader.loadSubScript("chrome://ellaunch/content/data_unix.js");
        }
    },
    complete: function()
    {
        elLaunch.observerService.removeObserver(elLaunch, "ellaunch-launch-request");
    },
    observe: function(subject, topic, data)
    {
        if (topic == "ellaunch-launch-request") {
            var url_raw = data;
            if ((pos = url_raw.indexOf("://")) == -1) return;

            var url_scheme = url_raw.substring(0, pos);
            var url_server = url_raw.substring(pos + 3);
            url_server = url_server.replace("+connect/", "");
            url_server = url_server.replace("/", "");
            var url_ip = '';
            var url_port = '';
            if ((pos = url_server.lastIndexOf(":")) == -1) {
                url_ip = url_server;
            } else {
                url_ip = url_server.substring(0, pos);
                url_port = url_server.substring(pos + 1);
            }

            var name = null;
            var path = null;
            var args = null;
            var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
            try {
                name = prefService.getComplexValue('extensions.ellaunch.game_' + url_scheme + '_name', Components.interfaces.nsISupportsString).data;
            } catch (e) {
                return;
            }
            try {
                var t_path = prefService.getComplexValue('extensions.ellaunch.game_' + url_scheme + '_path', Components.interfaces.nsISupportsString).data;

                // ファイルの存在チェック
                var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                file.initWithPath(t_path);
                if (file.exists()) {
                    path = t_path;
                }
            } catch (e) {
                path = '';
            }
            try {
                args = prefService.getComplexValue('extensions.ellaunch.game_' + url_scheme + '_args', Components.interfaces.nsISupportsString).data;
            } catch (e) {
                args = '';
            }

            args = args.replace('%IP%', url_ip);
            args = args.replace('%PORT%', url_port);

            if (!window.confirm(elLaunch.stringBundle.formatStringFromName("confirmJoin", [name, url_server], 2))) return;

            if (path.length == 0 && (url_scheme in games_path)) {

                // デフォルトパス
                if (games_path[url_scheme]['type'] == 1) {
                    // ファイルの存在チェック
                    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                    file.initWithPath(games_path[url_scheme]['path']);
                    if (file.exists()) {
                        path = games_path[url_scheme]['path'];
                    }
                // レジストリ
                } else if (games_path[url_scheme]['type'] == 2 && elLaunch.os == "WINNT") {
                    var reg = Components.classes["@mozilla.org/windows-registry-key;1"].createInstance(Components.interfaces.nsIWindowsRegKey);
                    reg.open(games_path[url_scheme]['root'], games_path[url_scheme]['key'], reg.ACCESS_READ);
                    var t_path = reg.readStringValue(games_path[url_scheme]['value']);
                    reg.close();

                    // ファイルの存在チェック
                    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                    file.initWithPath(t_path);
                    if (file.exists()) {
                        path = t_path;
                    }
                }
                if (path.length != 0 && ('suffix' in games_path[url_scheme])) {
                    path = path + games_path[url_scheme]['suffix'];
                }
            }

            if (path.length == 0) {
                var result = elLaunch.browseFile(name);
                if (result === false || result.length == 0) return;
                // ファイルの存在チェック
                var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                file.initWithPath(t_path);
                if (!file.exists()) return;

                path = result;

                // save to preference
                var pref_path = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
                pref_path.data = path;
                prefService.setComplexValue('extensions.ellaunch.game_' + url_scheme + '_path', Components.interfaces.nsISupportsString, pref_path);
            }

            // Launch!
            if (elLaunch.os == "WINNT") {
                var unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].getService(Components.interfaces.nsIScriptableUnicodeConverter);
                unicodeConverter.charset = "Shift_JIS";
                path = unicodeConverter.ConvertFromUnicode(path);

                var work_dir = null;
                if ((pos = path.lastIndexOf("\\")) !== -1) {
                    work_dir = path.substring(0, pos);
                }

                // @mozilla.org/process/util;1ではカレントディレクトリを設定出来ないため独自のXPCOM
                var elExec = Components.classes["@ayu.commun.jp/el/exec;1"].createInstance(Components.interfaces.IelExec);
                elExec.exec(path, args, work_dir);
            } else {
                var work_dir = null;
                if ((pos = path.lastIndexOf("/")) !== -1) {
                    work_dir = path.substring(0, pos);
                }

                // shellscript作成
                var sh_text = "#!/bin/sh\n\n";
                sh_text += "cd \"" + work_dir + "\"\n";
                sh_text += path + " " + args + "\n";

                // shellscript書き出し
                var tmp_file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("TmpD", Components.interfaces.nsIFile);
                tmp_file.append('ellaunch_' + Math.floor(Math.random() * 0xffffff).toString(16));
                tmp_file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0664);
                var tmp_localfile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                tmp_localfile.initWithPath(tmp_file.path);

                sh_text += "rm \"" + tmp_file.path + "\"\n";

                var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
                foStream.init(tmp_localfile, 0x02 | 0x08, 0664, 0);
                foStream.write(sh_text, sh_text.length);
                foStream.close();

                var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
                file.initWithPath("/bin/sh");
                var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
                process.init(file);
                var process_args = [tmp_localfile.path];
                process.run(false, process_args, process_args.length);
            }
        }
    },
    browseFile: function(name)
    {
        const filePicker = Components.classes['@mozilla.org/filepicker;1'].createInstance(Components.interfaces.nsIFilePicker);

        filePicker.init(window, elLaunch.stringBundle.formatStringFromName("browseExec", [name], 1), Components.interfaces.nsIFilePicker.modeOpen);
        filePicker.defaultString = "";
        var res = filePicker.show();
        switch (res) {
            case Components.interfaces.nsIFilePicker.returnOK:
                return filePicker.file.path;
        }
        return false;
    }
};

window.addEventListener('load', elLaunch.init, false);
window.addEventListener('unload', elLaunch.complete, false);
